/*
 * 2010-2011 mOcean Mobile. A subsidiary of Mojiva, Inc. All Rights Reserved.
 * 
 */


ORMMA_STATE_UNKNOWN  = "unknown";
ORMMA_STATE_HIDDEN   = "hidden";
ORMMA_STATE_DEFAULT  = "default";
ORMMA_STATE_EXPANDED = "expanded";
ORMMA_STATE_RESIZED = "resized";

ORMMA_EVENT_ERROR = "error";
ORMMA_EVENT_HEADING_CHANGE = "headingChange";
ORMMA_EVENT_KEYBOARD_CHANGE = "keyboardChange";
ORMMA_EVENT_LOCATION_CHANGE = "locationChange";
ORMMA_EVENT_NETWORK_CHANGE = "networkChange";
ORMMA_EVENT_ORIENTATION_CHANGE = "orientationChange";
ORMMA_EVENT_READY = "ready";
ORMMA_EVENT_RESPONSE = "response";
ORMMA_EVENT_SCREEN_CHANGE = "screenChange";
ORMMA_EVENT_SHAKE = "shake";
ORMMA_EVENT_SIZE_CHANGE = "sizeChange";
ORMMA_EVENT_STATE_CHANGE = "stateChange";
ORMMA_EVENT_TILT_CHANGE = "tiltChange";


(function() {

    /**
     * The main ad controller object
     */
    window.Ormma = {

        /**
         * The object that holds all types of OrmmaAdController events and associated listeners
         */
        events : [],

        /**
         * Holds the current dimension values
         */
        dimensions : {},

        /**
         * Holds the current property values
         */
        expandProperties :  {
			"use-background":false,
			"background-color" : "#000000",
			"background-opacity" : 1.0,
			"is-modal" : true},


		shakeProperties : {
			"interval" : "10",
			"intensity" : "20"
		},
		
		resizeProperties : { 
			transition : ORMMA_STATE_UNKNOWN 
		},
			
		state : ORMMA_STATE_DEFAULT,	
		lastState : ORMMA_STATE_DEFAULT,	

/**
	 * Use this method to subscribe a specific handler method to a specific
	 * event. In this way, multiple listeners can subscribe to a specific event, 
	 * and a single listener can handle multiple events. The events are:
	 *   
	 * <table>
	 *   <tr><td>ready</td><td>report initialize complete</td></tr>
	 *   <tr><td>network</td><td>report network connectivity changes</td></tr>
	 *   <tr><td>keyboard</td><td>report soft keyboard changes</td></tr>
	 *   <tr><td>orientation</td><td>report orientation changes</td></tr>
	 *   <tr><td>heading</td><td>report heading changes</td></tr>
	 *   <tr><td>location</td><td>report location changes</td></tr>
	 *   <tr><td>rotation</td><td>report rotation changes</td></tr>
	 *   <tr><td>shake</td><td>report device being shaken</td></tr>
	 *   <tr><td>state</td><td>report state changes</td></tr>
	 *   <tr><td>tilt</td><td>report tilt changes</td></tr>
	 * </table>
	 *
	 * <br/>#side effects: registering listeners for device features may power 
	 *                     up sensors in the device that will reduce the device
	 *                     battery life. 
	 * <br/>#ORMMA Level: 1 
	 *
	 * @param {String} event name of event to listen for
	 * @param {Function} listener function name / anonymous function to execute 
	 */
        /**
         * addEventListener adds an event listener to the listener array
         * @param {String} event The event name
         * @param {Function} listener The listener function
         * @returns nothing
         */
        addEventListener : function (event, listener) {
            if (typeof listener == 'function') {
                if (!this.events[event]) {
                    this.events[event] = [];
                }
                if (!this.events[event].listeners) {
                    this.events[event].listeners = [];
                }
                if (getListenerIndex(event, listener) === -1) {
                    this.events[event].listeners.splice(0, 0, listener);
                }
            }
        },
	
        /**
         * removeEventListener removes an event listener from the listener array
         * @param {String} event The event name
         * @param {Function} listener The listener function
         * @returns nothing
         */
        removeEventListener : function (event, listener) {
            if (typeof listener == 'function' && this.events[event] && this.events[event].listeners) {
                var listenerIndex = getListenerIndex(event, listener);
                if (listenerIndex !== -1) {
                    this.events[event].listeners.splice(listenerIndex, 1);
                }
            }
        },
	
	



		expand : function (dimensions, URL){

			this.dimensions = dimensions;
			_expand(dimensions, URL, this.expandProperties);
			var data = { dimensions : dimensions,
					 properties : this.expandProperties };
            Ormma.fireEvent('sizeChange', data);
            Ormma.fireEvent('stateChange', ORMMA_STATE_HIDDEN);			
		},

		unexpand : function (){
            Ormma.fireEvent('stateChange', ORMMA_STATE_DEFAULT);
		},


        /**
         * resize resizes the display window
         * @param {Object} dimensions The new dimension values of the window
         * @returns nothing
         */
        resize : function (width, height) {

//            this.dimensions = dimensions;

            _resize(width, height);

            var data = { dimensions : {width : width, height: height},
					 properties : this.expandProperties };
            Ormma.fireEvent(ORMMA_EVENT_SIZE_CHANGE, data);
            Ormma.fireEvent(ORMMA_EVENT_STATE_CHANGE, ORMMA_STATE_RESIZED);
        },


		getResizeProperties: function() {
			return this.resizeProperties;
		
		},

		setResizeProperties: function(properties) {
			this.resizeProperties = properties;
		
		},
		getExpandProperties: function() {
			return this.expandProperties;
		
		},

		setExpandProperties: function(properties) {
			this.expandProperties = properties;
		
		},



        /**
         * reset the window size to the original state
         * @param {Function} listener The listener function
         * @returns nothing
         */
        close : function () {

            _close();
            Ormma.fireEvent(ORMMA_EVENT_STATE_CHANGE, ORMMA_STATE_DEFAULT);
        },

        open : function (URL, controls) {
            _open(URL, controls);
            Ormma.fireEvent(ORMMA_EVENT_STATE_CHANGE, ORMMA_STATE_DEFAULT);
        },


        
        /**
         * Use this method to hide the web viewer.
         * @param none
         * @returns nothing
         */
		hide : function() {
			_hide();
			Ormma.fireEvent(ORMMA_EVENT_STATE_CHANGE, ORMMA_STATE_HIDDEN);
		},

		show : function() {
			_show();
			Ormma.fireEvent(ORMMA_EVENT_STATE_CHANGE, this.lastState);
		},
        /**
         * Use this method to get the current state of the web viewer. 
         * @param none
         * @returns boolean reflecting visible state
         */		
		getState : function() {
			return this.state;
		},
		
		setState : function(state) {
			this.state = state;
		},

// Level-2
		getHeading: function() {
			return _getHeading();
		},

		getLocation: function() {
			return _getLocation();
		},

		getNetwork: function() {
			return _getNetwork();
		},

		getTilt: function() {
			return _getTilt();
		},

		getResizeDimensions: function() {
			return dimensions;
		},

		getExpandProperties: function() {
			return this.expandProperties;
		},

		getScreenSize: function() {
			return _getScreenSize();
		},

		getShakeProperties: function() {
			return _getShakeProperties();
		},

		getSize: function() {
			return _getSize();
		},

		getMaxSize: function() {
			return _getMaxSize();
		},

		
		supports: function(feature) {
			return _supports(feature);
		
		},

		getResizeProperties: function() {
			return this.resizeProperties;
	
		},

		setResizeProperties: function(properties) {
			this.resizeProperties = properties;
		
		},
		getExpandProperties: function() {
			return this.expandProperties;
		
		},

		setExpandProperties: function(properties) {
			this.expandProperties = properties;
		
		},
		
		fireError: function(action, message){
			var data = { message : message,
					 action : action };
			Ormma.fireEvent(ORMMA_EVENT_ERROR, data);
		},
		
		//Level-2
		sendSMS: function(recipient, body){
			_sendSMS(recipient, body);
		},
		
		sendMail: function(recipient,subject,body){
		    window.external.sendMail(recipient,subject,body);
		},
		
		makeCall: function(number){
			_makeCall(number);
		},
		
		storePicture: function( url)
		{
		    _storePicture(url);
		},
		
        createEvent: function(date, title, body)
        {
            window.external.createEvent(date,title,body);
        },
        
        //Level-3
        addAsset: function( url, alias )
        {
            _addAsset( url, alias );
        },
		
        addAssets: function( assets )
        {
            _addAssets( assets );
        },
        
        getAssetURL: function( alias )
        {
            return _getAssetURL( alias );
        },
        
        getCacheRemaining: function()
        {
            return _getCacheRemaining();
        },
        
        removeAllAssets: function()
        {
            _removeAllAssets();
        },
        
        removeAsset: function( alias )
        {
            _removeAsset( alias );
        },
      
        request: function( val, prx )
        {
            return _request( val, prx );
        },
        
        /**
         * fireEvent fires an event
         * @private
         * @param {String} event The event name
         * @param {Object} additional information about the event
         * @returns nothing
         */

        fireEvent: function (event, args) {
            var len, i;
            if (Ormma.events[event] && Ormma.events[event].listeners) {
                len = Ormma.events[event].listeners.length;
                for (i = len-1; i >= 0; i--) {
                    (Ormma.events[event].listeners[i])(event, args);
                }
            }
        }
	};
    /**
     * The private methods
     */


   
    /**
     * getListenerIndex retrieves the index of listener from the event listener array
     * @private
     * @param {String} event The event name
     * @param {Function} listener The listener function
     * @returns the index value of the listener array, -1 if the listener doesn't exist
     */
    function getListenerIndex (event, listener) {
        var len, i;
        if (Ormma.events[event] && Ormma.events[event].listeners) {
            len = Ormma.events[event].listeners.length;
            for (i = len-1;i >= 0;i--) {
                if (Ormma.events[event].listeners[i] === listener) {
                    return i;
                }
            }
        }
        return -1;
    }


    /* implementations of public methods for specific vendors */

    function _expand(dimensions, URL, properties) {
        window.external.expand(convertJsonToString(dimensions), URL, properties);
    }

    function _open(URL, controls) {
        window.external.open(URL);
    }


    function _resize (width, height) {
        window.external.resize(width, height);
    }

    function _close () {
        window.external.close();
    }

	function _hide() {
		window.external.hide();
	}

	function _show() {
		window.external.show();
	}

	function _storePicture(url) {
		window.external.storePicture( url );
	}
	
    function _addAsset( url, alias )
    {
		window.external.addAsset( url, alias );
    }
    
    function _addAssets( assets )
    {
		window.external.addAsssets( assets );
    }
    
    function _getAssetURL( alias )
    {
		return window.external.getAssetURL( alias );
    }
    
    function _removeAllAssets()
    {
		window.external.removeAllAssets();
    }
    
    function _removeAsset(alias)
    {
		window.external.removeAsset(alias);
    }
    
    function _getCacheRemaining()
    {
		return window.external.getCacheRemaining();
    }
    
	function _getMaxSize(){
        return eval('('+window.external.getMaxSize()+')');
	}

	function _getSize(){
        return eval('('+window.external.getSize()+')');
	}

	function _supports(feature){
		return window.external.supports(feature);
	}

	function _getScreenSize() {
        return eval('('+window.external.getScreenSize()+')');
	}
	
	function _request(val, prx) {
        return window.external.request(val,prx);
	}
	
    function convertJsonToString(jsonData){
    var res = '{';

        for(var key in jsonData) {
        res += '"' + key + '"';
        res += ': ';
        res += '"' + jsonData[key] + '"';
        res += ', ';
       }
       
       res += '}';
    return res; 
    }
})();


function _fireOrmmaAssetReady( alias )
{
   Ormma.fireEvent('assetReady', alias);
}

function _fireOrmmaAssetRemoved( alias )
{
   Ormma.fireEvent('assetRemoved', alias);
}

function _fireOrmmaRequest( val )
{
   Ormma.fireEvent('response', val);
}
//alert("test");
